package com.ruoyi.generator.dao;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.dto.GenTableColumnDto;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class GenTableColumnDaoCustomImpl implements GenTableColumnDaoCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<GenTableColumn> findDbTableColumnsByName(String tableName) {
        List<Object> params = new ArrayList<>();
        StringBuilder sql = new StringBuilder();
        sql.append(" SELECT c.name as columnName, ");
        sql.append(" CASE WHEN c.is_nullable = 0 AND pk.column_id IS NULL THEN '1' ELSE NULL END as isRequired, ");
        sql.append(" CASE WHEN pk.column_id IS NOT NULL THEN '1' ELSE '0' END as isPk, ");
        sql.append(" c.column_id as sort, ");
        sql.append(" ISNULL(CAST(ep.value AS NVARCHAR(500)), '') as columnComment, ");
        sql.append(" CASE WHEN c.is_identity = 1 THEN '1' ELSE '0' END as isIncrement, ");
        sql.append(" t.name + CASE WHEN c.precision > 0 THEN '(' + CAST(c.precision AS VARCHAR) + CASE WHEN c.scale > 0 THEN ',' + CAST(c.scale AS VARCHAR) ELSE '' END + ')' ELSE '' END as columnType ");
        sql.append(" FROM sys.columns c ");
        sql.append(" INNER JOIN sys.types t ON c.user_type_id = t.user_type_id ");
        sql.append(" INNER JOIN sys.objects o ON c.object_id = o.object_id ");
        sql.append(" LEFT JOIN sys.extended_properties ep ON ep.major_id = c.object_id AND ep.minor_id = c.column_id AND ep.name = 'MS_Description' ");
        sql.append(" LEFT JOIN ( ");
        sql.append("   SELECT ic.column_id, ic.object_id ");
        sql.append("   FROM sys.index_columns ic ");
        sql.append("   INNER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id ");
        sql.append("   WHERE i.is_primary_key = 1 ");
        sql.append(" ) pk ON pk.object_id = c.object_id AND pk.column_id = c.column_id ");
        sql.append(" WHERE o.type = 'U' AND o.name = ? ");
        if (StringUtils.isNotBlank(tableName)) {
            params.add(tableName);
        }
        sql.append(" ORDER BY c.column_id ");
        Query contentQuery = entityManager.createNativeQuery(sql.toString());
        for (int i = 0; i < params.size(); i++) {
            contentQuery.setParameter(i + 1, params.get(i));
        }
        contentQuery.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(GenTableColumnDto.class));
        List<GenTableColumnDto> results = contentQuery.getResultList();
        List<GenTableColumn> result = format(results);
        return result;
    }


    private List<GenTableColumn> format(List<GenTableColumnDto> list) {
        List<GenTableColumn> collect = list.stream().map(dto -> {
            GenTableColumn genTable = new GenTableColumn();
            BeanUtils.copyProperties(dto, genTable);
            return genTable;
        }).collect(Collectors.toList());
        return collect;
    }

}
